package com.qire.manhua.model.viewModel.impl;

import android.graphics.Color;
import android.text.Html;
import android.view.View;
import android.widget.BaseAdapter;

import com.qire.antscore.annotation.PropertyObserve;
import com.qire.common.basic.ObjectUtil;
import com.qire.common.basic.StringUtil;
import com.qire.common.collect.ListUtil;
import com.qire.common.support.base.BaseViewModel;
import com.qire.common.support.base.IViewModel;
import com.qire.common.widget.adapter.auto.AutoVariable;
import com.qire.common.widget.adapter.auto.SummerBindAdapter;
import com.qire.common.widget.adapter.auto.annotation.AdapterEntityBind;
import com.qire.manhua.BR;
import com.qire.manhua.R;
import com.qire.manhua.controller.ComicSearchController;
import com.qire.manhua.dal.service.ComicSearchService;
import com.qire.manhua.databinding.LayoutComicSearchGuessItemBinding;
import com.qire.manhua.databinding.LayoutComicSearchHistoryItemBinding;
import com.qire.manhua.databinding.LayoutComicSearchHotItemBinding;
import com.qire.manhua.databinding.LayoutComicSearchRecommendItemBinding;
import com.qire.manhua.databinding.LayoutComicSearchResultItemBinding;
import com.qire.manhua.model.entity.ComicBookEntity;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
import java.util.StringJoiner;

import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;
import androidx.lifecycle.MutableLiveData;

public class ComicSearchViewModel extends BaseViewModel<IViewModel> implements IViewModel {

    private ComicSearchService searchService = new ComicSearchService(this);

    private final ArrayList<SearchHotItemViewModel> hotItemList = new ArrayList<>();
    private final ArrayList<SearchGuessItemViewModel> guessItemList = new ArrayList<>();
    private final ArrayList<SearchResultItemViewModel> resultItemList = new ArrayList<>();
    private final ArrayList<SearchHistoryItemViewModel> historyItemList = new ArrayList<>();
    private final ArrayList<SearchRecommendItemViewModel> recommendItemList = new ArrayList<>();

    private final SummerBindAdapter<SearchHotItemViewModel> hotAdapter = new SummerBindAdapter<>(hotItemList);
    private final SummerBindAdapter<SearchGuessItemViewModel> guessAdapter = new SummerBindAdapter<>(guessItemList);
    private final SummerBindAdapter<SearchResultItemViewModel> resultAdapter = new SummerBindAdapter<>(resultItemList);
    private final SummerBindAdapter<SearchHistoryItemViewModel> historyAdapter = new SummerBindAdapter<>(historyItemList);
    private final SummerBindAdapter<SearchRecommendItemViewModel> recommendAdapter = new SummerBindAdapter<>(recommendItemList);

    public ComicSearchViewModel() {
        toggleGuessPanel(true);
        toggleRecommendPanel(true);
        toggleResultPanel(true);
        setSearchWords("");
    }

    @Override
    public int getVariableId() {
        return BR.comicSearchViewModel;
    }

    //region    #附加管理 begin
    /**
     * 附加属性绑定
     */
    public void onAddition(ComicSearchController controller) {
        this.hotAdapter.setEventProcess(controller);
        this.guessAdapter.setEventProcess(controller);
        this.resultAdapter.setEventProcess(controller);
        this.historyAdapter.setEventProcess(controller);
        this.recommendAdapter.setEventProcess(controller);
    }

    /**
     * 清理函数，在Activity退出时，ViewModel生命周期到期会被回收，调用该事件，
     * 页面由于切换、横竖屏转换、内存回收等情况并不会影响到ViewModel的生命周期。
     */
    @Override
    protected void onCleared() {
        super.onCleared();
        this.searchService = null;
        this.hotAdapter.setEventProcess(null);
        this.guessAdapter.setEventProcess(null);
        this.resultAdapter.setEventProcess(null);
        this.historyAdapter.setEventProcess(null);
        this.recommendAdapter.setEventProcess(null);
    }
    //endregion #附加管理 end

    //region    #数据业务 begin

    // 预测联想搜索词
    public void clearGuessItemList() {
        guessItemList.clear();
    }
    public void addGuessItem(int comicId, String comicName) {
        guessItemList.add(new SearchGuessItemViewModel(new ComicBookEntity(comicId, comicName)));
    }
    public void refreshGuessAdapter() {
        guessAdapter.notifyDataSetChanged();
    }

    // 加载热门搜索词数据
    public void loadSearchHotData() {
        searchService.loadHotSearchData();
    }
    public void clearHotItemList() {
        hotItemList.clear();
    }
    public void addHotItem(int comicId, String comicName) {
        hotItemList.add(new SearchHotItemViewModel(new ComicBookEntity(comicId, comicName)));
    }
    public void refreshHotAdapter() {
        hotAdapter.notifyDataSetChanged();
    }

    // 加载历史搜索词数据
    public void loadSearchHistoryData() {
        searchService.loadHistorySearchData();
    }
    public void clearHistoryItemList() {
        historyItemList.clear();
    }
    public void addFirstHistoryItem(String searchWords) {
        historyItemList.add(0, new SearchHistoryItemViewModel(searchWords));
    }
    public void addHistoryItem(String searchWords) {
        historyItemList.add(new SearchHistoryItemViewModel(searchWords));
    }
    public void refreshHistoryAdapter() {
        historyAdapter.notifyDataSetChanged();
    }

    // 清理历史搜索此数据
    public boolean isSearchHistoryEmpty() {
        return ListUtil.isEmpty(historyItemList);
    }
    public void clearHistoryData() {
        searchService.removeHistorySearchData();
        clearHistoryItemList();
        refreshHistoryAdapter();
    }

    // 获得搜索关键字
    public String searchWords() {
        return getToValue("searchWords");
    }

    // 搜索漫画
    public void searchComic() {
        int pageNo = 1; // 服务器没有实现分页，但要求传递这个字段故保留默认为1
        String searchWords = searchWords();
        searchService.searchComic(searchWords, pageNo);

        Iterator<SearchHistoryItemViewModel> historyIterator = historyItemList.iterator();
        while (historyIterator.hasNext()) {
            SearchHistoryItemViewModel itemViewModel = historyIterator.next();
            if(searchWords.equals(itemViewModel.searchWords)) {
                historyItemList.remove(itemViewModel);
                break;
            }
        }
        addFirstHistoryItem(searchWords);
        refreshHistoryAdapter();
        toggleButtonPanel(0);
    }

    public void clearRecommendItemList() {
        recommendItemList.clear();
    }
    public void addRecommendItem(int comicId, String cover, String title, String[] tag) {
        recommendItemList.add(new SearchRecommendItemViewModel(comicId, cover, title, tag));
    }

    public void clearResultItemList() {
        resultItemList.clear();
    }
    public void addResultSeparate() {
        resultItemList.add(new SearchResultItemViewModel());
    }
    public void addResultItem(int comicId, String cover, String title, String author, int popularity, String describe) {
        resultItemList.add(new SearchResultItemViewModel(comicId, cover, title, author, popularity, describe));
    }

    //endregion #数据业务 end

    //region    #UI操作 begin

    public void refreshSearchResultUI(int resultCount) {
        resultAdapter.notifyDataSetChanged();
        recommendAdapter.notifyDataSetChanged();

        final String FORMAT_SEARCH_NOTHING = "搜索“<font color=#ff9024>%s</font>”结果，共<font color=#ff9024>%d</font>条";
        final String searchWords = StringUtil.abbreviation(searchWords(), 10, "...");
        CharSequence resultTipsText = Html.fromHtml(String.format(Locale.getDefault(), FORMAT_SEARCH_NOTHING, searchWords, resultCount));
        set("resultTipsText", resultTipsText);

        toggleGuessPanel(true);
        toggleResultPanel(ListUtil.isEmpty(resultItemList));
        toggleRecommendPanel(ListUtil.isEmpty(recommendItemList));
    }

    public void setSearchWords(String searchWords) {
        set("searchWords", searchWords);
    }

    @PropertyObserve(name = "searchWords")
    public void onSearchWordsChange(String searchWords) {
        boolean isEmptyWords = StringUtil.isEmpty(searchWords);
        toggleButtonPanel(isEmptyWords ? 0 : 1);
        set("clearSearchWordsVisible", isEmptyWords ? View.GONE : View.VISIBLE);
        toggleGuessPanel(isEmptyWords);
        if(!isEmptyWords) {
            searchService.guessAssociativeWords(searchWords);
        }
    }

    public void toggleButtonPanel(int pageNo) {
        set("buttonPanelNo", pageNo);
    }

    public void toggleGuessPanel(boolean isHide) {
        set("guessPanelVisible", isHide ? View.GONE : View.VISIBLE);
    }

    public void toggleRecommendPanel(boolean isHide) {
        set("recommendPanelVisible", isHide ? View.GONE : View.VISIBLE);
    }

    public void toggleResultPanel(boolean isHide) {
        set("resultPanelVisible", isHide ? View.GONE : View.VISIBLE);
    }

    //endregion #UI操作 end

    //region    #UI绑定 begin

    public MutableLiveData<Integer> getGuessPanelVisible() {
        return get("guessPanelVisible");
    }

    public MutableLiveData<Integer> getRecommendPanelVisible() {
        return get("recommendPanelVisible");
    }

    public MutableLiveData<Integer> getResultPanelVisible() {
        return get("resultPanelVisible");
    }

    public MutableLiveData<String> getSearchWords() {
        return get("searchWords");
    }

    public MutableLiveData<Integer> getClearSearchWordsVisible() {
        return get("clearSearchWordsVisible");
    }

    public MutableLiveData<Integer> getButtonPanelNo() {
        return get("buttonPanelNo");
    }

    public MutableLiveData<CharSequence> getResultTipsText() {
        return get("resultTipsText");
    }


    public BaseAdapter getHotAdapter() {
        return hotAdapter;
    }
    public BaseAdapter getHistoryAdapter() {
        return historyAdapter;
    }
    public BaseAdapter getGuessAdapter() {
        return guessAdapter;
    }
    public BaseAdapter getRecommendAdapter() {
        return recommendAdapter;
    }
    public BaseAdapter getResultAdapter() {
        return resultAdapter;
    }

    //endregion #UI绑定 end

    @AdapterEntityBind(viewRid = R.layout.layout_comic_search_hot_item)
    public class SearchHotItemViewModel extends BaseObservable implements AutoVariable<LayoutComicSearchHotItemBinding> {

        private final ComicBookEntity comicBookEntity;

        public SearchHotItemViewModel(ComicBookEntity comicBookEntity) {
            this.comicBookEntity = comicBookEntity;
        }

        @Override
        public void bindVariable(LayoutComicSearchHotItemBinding viewBind) {
            viewBind.setSearchHotItemViewModel(this);
        }

        public int comicId() {
            return comicBookEntity.id;
        }

        @Bindable
        public CharSequence getTitle() {
            return comicBookEntity.bookName;
        }

    }

    @AdapterEntityBind(viewRid = R.layout.layout_comic_search_history_item)
    public class SearchHistoryItemViewModel extends BaseObservable implements AutoVariable<LayoutComicSearchHistoryItemBinding> {

        public final String searchWords;

        public SearchHistoryItemViewModel(String searchWords) {
            this.searchWords = searchWords;
        }

        @Override
        public void bindVariable(LayoutComicSearchHistoryItemBinding viewBind) {
            viewBind.setSearchHistoryItemViewModel(this);
        }

        @Bindable
        public CharSequence getSearchWords() {
            return searchWords;
        }

    }

    @AdapterEntityBind(viewRid = R.layout.layout_comic_search_guess_item)
    public class SearchGuessItemViewModel extends BaseObservable implements AutoVariable<LayoutComicSearchGuessItemBinding> {

        private final ComicBookEntity comicBookEntity;

        public SearchGuessItemViewModel(ComicBookEntity comicBookEntity) {
            this.comicBookEntity = comicBookEntity;
        }

        public int comicId() {
            return comicBookEntity.id;
        }

        public void saveSearchRecommend() {
            searchService.saveSearchWords(comicBookEntity.bookName);
            addFirstHistoryItem(comicBookEntity.bookName);
            refreshHistoryAdapter();
        }

        @Override
        public void bindVariable(LayoutComicSearchGuessItemBinding viewBind) {
            viewBind.setSearchGuessItemViewModel(this);
        }

        @Bindable
        public CharSequence getTitle() {
            return StringUtil.dye(comicBookEntity.bookName, searchWords(), Color.rgb(0xff, 0x92, 0x04));
        }

    }

    @AdapterEntityBind(viewRid = R.layout.layout_comic_search_recommend_item)
    public class SearchRecommendItemViewModel extends BaseObservable implements AutoVariable<LayoutComicSearchRecommendItemBinding> {

        public final int comicId;
        private final String cover;
        private final String title;
        private final String[] tags;

        public SearchRecommendItemViewModel(int comicId, String cover, String title, String[] tags) {
            this.comicId = comicId;
            this.cover = cover;
            this.title = title;
            this.tags = tags;
        }

        @Override
        public void bindVariable(LayoutComicSearchRecommendItemBinding viewBind) {
            viewBind.setSearchRecommendItemViewModel(this);
        }

        @Bindable
        public String getCover() {
            return cover;
        }

        @Bindable
        public CharSequence getTitle() {
            return title;
        }

        @Bindable
        public CharSequence getTag() {
            StringBuilder tagBuilder = new StringBuilder();
            for (String tag : tags) {
                tagBuilder.append(tag).append(" ");
            }
            return tagBuilder.toString();
        }

    }

    @AdapterEntityBind(viewRid = R.layout.layout_comic_search_result_item)
    public class SearchResultItemViewModel extends BaseObservable implements AutoVariable<LayoutComicSearchResultItemBinding> {

        public final int comicId;

        private final String cover;
        private final CharSequence title;
        private final CharSequence author;
        private final int popularity;
        private final CharSequence describe;
        private final boolean isResult;

        public SearchResultItemViewModel() {
            this(0, "", "", "", 0, "", false);
        }

        public SearchResultItemViewModel(int comicId, String cover, String title, String author, int popularity, String describe) {
            this(comicId, cover, title, author, popularity, describe, true);
        }
        public SearchResultItemViewModel(int comicId, String cover, String title, String author, int popularity, String describe, boolean isResult) {
            final String searchWords = searchWords();
            final int dyeColor = Color.rgb(0xff, 0x92, 0x04);

            this.comicId = comicId;
            this.cover = cover;
            this.title = StringUtil.dye(title, searchWords, dyeColor);
            this.author = StringUtil.dye("作者：" + author, searchWords, dyeColor);
            this.popularity = popularity;
            this.describe = StringUtil.dye(describe, searchWords, dyeColor);
            this.isResult = isResult;
        }

        @Override
        public void bindVariable(LayoutComicSearchResultItemBinding viewBind) {
            viewBind.setSearchResultItemViewModel(this);
        }

        @Bindable
        public int getPanelNo() {
            return isResult ? 0 : 1;
        }

        @Bindable
        public String getCover() {
            return cover;
        }

        @Bindable
        public CharSequence getTitle() {
            return title;
        }

        @Bindable
        public CharSequence getAuthor() {
            return author;
        }

        @Bindable
        public CharSequence getPopularityValue() {
            return "人气值：" + StringUtil.toSymbol(popularity);
        }

        @Bindable
        public CharSequence getDescribe() {
            return describe;
        }

    }
}
